/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * File Name          :
 * Description        :
 ******************************************************************************
 * @attention
 *
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "main.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
typedef struct
{
    char count;
    int Value[3];
} MotorTempStruct;
typedef struct
{
    int version1;
    int version2;
    uint16_t VERSION;
} VersionStruct;
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define MOTOR_TEMP_NUM 3
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
MotorTempStruct MotorTempSensor;
VersionStruct VersionData;
/* USER CODE END Variables */

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
static void ADCx_ENABLE(ADC_TypeDef *ADCx)
{
    LL_ADC_StartCalibration(ADCx, LL_ADC_SINGLE_ENDED);
    while (LL_ADC_IsCalibrationOnGoing(ADCx) != 0)
    {
    }
    LL_ADC_Enable(ADCx);
    while (LL_ADC_IsActiveFlag_ADRDY(ADCx) == 0)
    {
    }
}
static void ADCx_REG_Start(ADC_TypeDef *ADCx)
{
    LL_ADC_REG_StartConversion(ADCx);
    while (LL_ADC_IsActiveFlag_EOC(ADCx) == 0)
    {
    }
    LL_ADC_ClearFlag_EOC(ADCx);
    LL_ADC_ClearFlag_EOS(ADCx);
}

static void ADC3_REG_SampleConfig(uint8_t config)
{
    switch (config)
    {
    case 0:
        LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_9);
        LL_ADC_SetChannelSamplingTime(ADC3, LL_ADC_CHANNEL_9, LL_ADC_SAMPLINGTIME_2CYCLES_5);
        LL_ADC_SetChannelSingleDiff(ADC3, LL_ADC_CHANNEL_9, LL_ADC_SINGLE_ENDED);
        break;
    case 1:
        LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_10);
        LL_ADC_SetChannelSamplingTime(ADC3, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_2CYCLES_5);
        LL_ADC_SetChannelSingleDiff(ADC3, LL_ADC_CHANNEL_10, LL_ADC_SINGLE_ENDED);
        break;
    case 2:
        LL_ADC_REG_SetSequencerRanks(ADC3, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_10);
        LL_ADC_SetChannelSamplingTime(ADC3, LL_ADC_CHANNEL_10, LL_ADC_SAMPLINGTIME_2CYCLES_5);
        LL_ADC_SetChannelSingleDiff(ADC3, LL_ADC_CHANNEL_10, LL_ADC_SINGLE_ENDED);
        break;
    }
}
void HardwareVersion_Acquire(void)
{
    g_sys.Para.HW_Version = VersionData.VERSION;
}
void AnalogSensor_Init(void)
{
    // acquire version of hardware
    ADCx_ENABLE(ADC1);
    ADCx_ENABLE(ADC2);
#define SAMPLE_TIMES 10
    for (int i = 0; i < (SAMPLE_TIMES - 1); i++)
    {
        ADCx_REG_Start(ADC1);
        ADCx_REG_Start(ADC2);
        VersionData.version2 += LL_ADC_REG_ReadConversionData12(ADC2);
        VersionData.version1 += LL_ADC_REG_ReadConversionData12(ADC1);
    }
    VersionData.version1 /= (SAMPLE_TIMES * 6553);
    VersionData.version2 /= (SAMPLE_TIMES * 6553);
    VersionData.VERSION = (VersionData.version1 * 10 + VersionData.version2);
    HardwareVersion_Acquire();
#undef SAMPLE_TIMES
    // MotorTemperatureSensor
    // PD12   ------> ADC3_IN9
    // PD13   ------> ADC3_IN10
    // PD14   ------> ADC3_IN11
    ADCx_ENABLE(ADC3);
    static uint8_t count = 0;
    while (count < (MOTOR_TEMP_NUM * 10))
    {
        MotorTemperatureSensor_Acquire();
        count++;
    }
    count = 0;
}

void MotorTemperatureSensor_Acquire(void)
{
    ADC3_REG_SampleConfig(MotorTempSensor.count);
    ADCx_REG_Start(ADC3);
    MotorTempSensor.Value[MotorTempSensor.count] = LL_ADC_REG_ReadConversionData12(ADC3);

    // three times updata once
    MotorTempSensor.count++;
    if (MotorTempSensor.count >= MOTOR_TEMP_NUM)
    {
        MotorTempSensor.count = 0;
        float _Calc = utils_min_abs((MotorTempSensor.Value[2]),
                                    (utils_min_abs(MotorTempSensor.Value[0], MotorTempSensor.Value[1])));
        if (_Calc < 45200)
        {
            _Calc = -35.24f * log(_Calc) + 382.0f;
        }
        else
        {
            _Calc = -0.00000008f * _Calc * _Calc + 0.0066f * _Calc - 135.0f;
        }
        g_sys.Para.MotorTmp = _Calc;
    }
}

void BusVolt_Acquire(void)
{
    int Ubus_ADC;
    Ubus_ADC = ADC1->JDR2 & 0xffff;
    // 120K / 4.7K   
    g_sys.Para.VoltBus = (float)(Ubus_ADC) * 0.001335f;// value / 65535.0f * 3.3 / 0.0377;
}
//Brake resistor feedback voltage
void BrakeVolt_Acquire(void)
{
    int Brake_ADC;
    float _Calc;
    Brake_ADC = ADC2->JDR2 & 0xffff;
    //Rshunt 0.2R   Gain 13.4
    _Calc = (float)(Brake_ADC) * 0.00002f ;//value / 65535.0f * 3.3 / 100 / 3 * 23 / 0.2R

    g_sys.Para.CurrentBrake = (0.02f * g_sys.Para.CurrentBrake) + (0.98f * _Calc);
}

/* USER CODE END Application */
